#coding=utf-8
import types
from xml.dom.minidom import parse
import xml.dom.minidom

from content_recommender_core import config
from sklearn.neighbors import NearestNeighbors
from Course import *
from Person import Person

class Recommendation:
    Course_data=Course_data.Course_data   #标定类型方便操作
    Person= Person.Person
    def __init__(self,Course_data,Person):
        self.Course_data=Course_data
        self.Person=Person
        self.recommend_data=[]
        for iter in self.Person.course:#对课程列表对象进行归一化处理
            iter.DealData(self.Course_data.getMaxMinlist()[0],self.Course_data.getMaxMinlist()[1])
        Course_data.setN(config.DATA_CLASSIFICATION_NUMBER)#设置课程属性分类
    def recommend(self,positions=0,weights=1,date=0):
        '''
        :return: 返回推荐列表
        '''
        self.changeDataweight(positions, weights)
        flag=False#是否存在数据标志
        count=0#执行推荐次数统计
        kind = self.Course_data.cluster_kind()  # 原始数据分类列表
        while (flag==False)&(count<=100):#如果存在数据或者推荐次数超过100次则停止推荐
            kind_person_kind=[]#预测数据的分类列表
            data_range=[]#所在范围的数据分类所对应的索引值
            data=[]#范围内所在类别列表得索引值
            for i in range(len(self.Person.course)):#确定预测课程的分类列表
                kind_person_kind.append(self.Course_data.cluster_predict
                                        (self.Person.course[i].getData()))
            for i in range(len(self.Person.course)):#确定预测课程范围内的分类列表
                data_range.append(NearestNeighbors().
                                  fit(self.Course_data.getDealdaMat()).radius_neighbors(self.Person.course[i].getData()
                                                                                        , config.RECOMMENDED_CORE_SENSITIVITY, return_distance=False))
            for i in range(len(self.Person.course)):#确定相匹配的课程分类
                for j in range(data_range[i][0].shape[0]):
                    if(kind[data_range[i][0][j]]==kind_person_kind[i]):
                        data.append(data_range[i][0][j])
            if len(data)!=0:
                self.recommend_data = data
                data = self.dealopenSemester(date)
                if len(data)!=0:
                    flag = True  # 如果存在数据，标志标为TRUE
            count+=1#每推荐结束一次，count加一
        return self

    def changeDataweight(self,positions,weights):
        '''
        :param positions: 推荐系统核心权值修改位置
        :param weights: 推荐系统核心权值为原来的倍数
        '''
        self.Course_data.changeWeight(positions,weights)
        for iter in self.Person.course:
            iter.changeDataweight(positions,weights)

    def dealopenSemester(self,date=0):
        '''
        :param date: 希望推荐课程的日期
        :return: 推荐列表
        '''
        data=self.recommend_data
        if date==0:
            return data
        data_date = []
        daMat=[]
        for iter in data:
            data_date.append((self.Course_data.data[iter][9]))#提取推荐课程的开课日期
        if type(date) is types.IntType:#如果类型为int
                for i in range(len(data_date)):
                    if date==data_date[i]:#筛选推荐信息
                        daMat.append(data[i])
        else:
            for iter in date:
                for i in range(len(data_date)):
                    if iter==data_date[i]:#筛选推荐信息
                        daMat.append(data[i])
        self.recommend_data=daMat
        return daMat
    def analysis(self):
        DOMTree = xml.dom.minidom.parse(config.ORIGINAL_DATA_XML_FILE_PATH)
        collection = DOMTree.documentElement
        courses = collection.getElementsByTagName("course")
        daMat=[]
        data=[]
        for course in courses:
            data.append([course.getElementsByTagName('c_no')[0].childNodes[0].data,
                       course.getElementsByTagName('chinese_name')[0].childNodes[0].data,
                       course.getElementsByTagName('english_name')[0].childNodes[0].data,
                       course.getElementsByTagName('academy_no')[0].childNodes[0].data,
                       course.getElementsByTagName('credit')[0].childNodes[0].data,
                       course.getElementsByTagName('class_hours')[0].childNodes[0].data,
                       course.getElementsByTagName('theory_hours')[0].childNodes[0].data,
                       course.getElementsByTagName('experiment_hours')[0].childNodes[0].data,
                       course.getElementsByTagName('computer_hours')[0].childNodes[0].data,
                       course.getElementsByTagName('practice_hours')[0].childNodes[0].data,
                       course.getElementsByTagName('week_hours')[0].childNodes[0].data,
                       course.getElementsByTagName('emester')[0].childNodes[0].data
                       ])
        for iter in self.recommend_data:
            str=''
            for i in data[iter]:
               str+=i.encode('utf-8')+'\t'
            daMat.append(str[:-2])  # 去除结尾\n
        return daMat

